# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo
from PyQt5.QtCore import pyqtSignal, QThread, QObject, QTimer
import moudles.tool.tLog as tLog

class tSerialPort(QObject):
    # private signal

    # public signal
    sigPortChanged = pyqtSignal(int)
    sigSendStatusChanged = pyqtSignal(int)
    sigRecvDone = pyqtSignal(list)

    def __init__(self):
        super().__init__()

    def init(self):
        self.port = QSerialPort()

        print('port init success')
        tLog.putThreadId(str(tSerialPort))

        self.port.readyRead.connect(self.portRecvDone)
        self.port.bytesWritten.connect(self.portSendDone)

    def portOpen(self, name:str, baud:int=115200, databit:int=QSerialPort.Data8, stopbit:int=QSerialPort.OneStop, verifyBit:int=QSerialPort.NoParity):
        # print(name, baud, databit, stopbit, verifyBit)
        # 不打开已经打开的端口
        if self.port.isOpen() and self.port.portName() == name.strip():
            return
        else:
            self.port.close()

        self.port.setPortName(name.strip())
        self.port.setBaudRate(baud)
        self.port.setDataBits(databit)
        self.port.setStopBits(stopbit)
        self.port.setParity(verifyBit)

        status = self.port.open(QSerialPort.ReadWrite)
        if status:
            self.port.setDataTerminalReady(True)
            self.sigPortChanged.emit(1)
            # print("Port status", "串口打开成功！")
        else:
            self.sigPortChanged.emit(-1)
            # print("Port Error", "串口打开失败！")

    def portClose(self, name:str):
        self.port.close()
        self.sigPortChanged.emit(0)

    def portRecvDone(self):
        recvData = []
        while self.port.bytesAvailable():
            temp = int.from_bytes(self.port.read(1), byteorder='big',signed=False)
            recvData.append(temp)

        self.sigRecvDone.emit(recvData)

    def portSendDone(self):
        self.sigSendStatusChanged.emit(0)

    def portSendData(self, data:list):
        self.sigSendStatusChanged.emit(1)
        self.port.write(bytes(data))

class tSerialThread(QObject):
    # serial port use signal
    sigPortOpen = pyqtSignal(str, int, int, int, int)
    sigPortClose = pyqtSignal(str)
    sigPortSend = pyqtSignal(list)

    # super thread signal
    sigRecvDone = pyqtSignal(list, int, int)
    sigPortChanged = pyqtSignal(int)
    sigSendChanged = pyqtSignal(int, int)

    def __init__(self):
        super().__init__()

        self.portThread = QThread()
        self.portThread.setObjectName('serial thread')
        self.port = tSerialPort()
        self.port.moveToThread(self.portThread)

        self.paramInit()
        self.sigSlotInit()
        self.portThread.start()

    def paramInit(self):
        self.txBusy = 0
        self.txCnt  = 0
        self.rxCnt  = 0

    def sigSlotInit(self):
        self.portThread.started.connect(self.port.init)
        self.portThread.finished.connect(self.portThread.deleteLater)

        self.sigPortOpen.connect(self.port.portOpen)
        self.sigPortClose.connect(self.port.portClose)
        self.sigPortSend.connect(self.port.portSendData)

        self.port.sigSendStatusChanged.connect(self.slotPortSendStatusChanged)
        self.port.sigRecvDone.connect(self.slotPortRecvDone)
        self.port.sigPortChanged.connect(self.portChangedProcess)

    def portOpen(self, name:str, baud=115200, databit=8, stopbit=0, verifyBit=0):
        # print('emit port open evt to serial port open object')
        self.sigPortOpen.emit(name, baud, databit, stopbit, verifyBit)

    def portClose(self, name:str):
        # print('emit port close evt to serial port close object')
        self.sigPortClose.emit(name)

    def portChangedProcess(self, val:int):
        self.sigPortChanged.emit(val)

    def portSend(self, arr:list):
        self.txCnt += len(arr)
        self.sigPortSend.emit(arr)

    def slotPortSendStatusChanged(self, flag):
        if self.txBusy != flag:
            self.txBusy = flag
            self.sigPortSendChanged.emit(self.txBusy, self.txCnt)

    def slotPortRecvDone(self, arr:list):
        cnt = len(arr)
        self.rxCnt += cnt
        # print(self.rxCnt, arr)
        self.sigRecvDone.emit(arr, cnt, self.rxCnt)

    def getTxCnt(self):
        return self.rxCnt

    def getRxCnt(self):
        return self.rxCnt

    def clearTransferCount(self):
        self.txCnt = 0
        self.rxCnt = 0
